package com.databuff;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import java.io.*;
import java.security.Key;
import java.security.SecureRandom;

/**
 * @author:TianMing
 * @date: 2020/9/25
 * @time: 10:07
 */
public class EncryptDecryptUtil {
    private static final String DESEDE = "DESede";
    private static final String AES = "AES";
    private Key key;

    public EncryptDecryptUtil(String str, String alg) {
        //生成密匙
        getKey(str,alg);

    }
    /**
     * 根据参数生成KEY
     */
    public void getKey(String strKey,String alg) {
        try {
            KeyGenerator _generator = KeyGenerator.getInstance(alg);
            if (AES.equals(alg)){
                SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
                secureRandom.setSeed(strKey.getBytes());
                _generator.init(128,secureRandom);
            }else if(DESEDE.equals(alg)){
                SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
                secureRandom.setSeed(strKey.getBytes());
                _generator.init(112,secureRandom);
            }else {
                _generator.init(new SecureRandom(strKey.getBytes()));
            }
            this.key = _generator.generateKey();
            _generator = null;
        } catch (Exception e) {
            throw new RuntimeException("Error initializing SqlMap class. Cause: " + e);
        }
    }

    /**
     * 文件file进行加密并保存目标文件destFile中
     *
     * @param file   要加密的文件 如c:/test/srcFile.txt
     * @param destFile 加密后存放的文件名 如c:/加密后文件.txt
     */
    public void encrypt(String file, String destFile,String alg) throws Exception {
        InputStream is = null;
        OutputStream out = null;
        CipherInputStream cis = null;
        try{
            Cipher cipher = Cipher.getInstance(alg);
            cipher.init(Cipher.ENCRYPT_MODE, this.key);
            is = new FileInputStream(file);
            out = new FileOutputStream(destFile);
            cis = new CipherInputStream(is, cipher);
            byte[] buffer = new byte[1024];
            int r;
            while ((r = cis.read(buffer)) > 0) {
                out.write(buffer, 0, r);
            }
        }catch (Exception e) {
          throw  e;
        } finally {
            try {
                if (cis != null) {cis.close();}
            } catch (IOException e) {}
            try {
                if (is != null) {is.close();}
            } catch (IOException e) {}
            try {
                if (out != null) {out.close();}
            } catch (IOException e) {}
        }
    }
    /**
     * 文件采用DES算法解密文件
     *
     * @param file 已加密的文件 如c:/加密后文件.txt
     *         * @param destFile
     *         解密后存放的文件名 如c:/ test/解密后文件.txt
     */
    public void decrypt(String file, String dest,String alg) throws Exception {
        InputStream is = null;
        OutputStream out = null;
        CipherOutputStream cos = null;
        try{
            Cipher cipher = Cipher.getInstance(alg);
            cipher.init(Cipher.DECRYPT_MODE, this.key);
            is = new FileInputStream(file);
            out = new FileOutputStream(dest);
            cos = new CipherOutputStream(out, cipher);
            byte[] buffer = new byte[1024];
            int r;
            while ((r = is.read(buffer)) >= 0) {
                cos.write(buffer, 0, r);
            }
        }catch (Exception e) {
            throw  e;
        } finally {
            try {
                if (cos != null) {cos.close();}
            } catch (IOException e) {}
            try {
                if (is != null) {is.close();}
            } catch (IOException e) {}
            try {
                if (out != null) {out.close();}
            } catch (IOException e) {}
        }
    }

    public static void main(String[] args) {
        if(args.length < 2){
            System.out.println("------需要加密文件url及保存目录url");
            return;
        }
        String srcUrl = args[0];
        String destDirUrl = args[1];
        try {
            String DESedeKey = "MjAyMDA5MjVEY3puQDEyM0RFU2VkZQ==";
            EncryptDecryptUtil desded = new EncryptDecryptUtil(Base64ConvertUtil.decode(DESedeKey), DESEDE);

            // String version = "v3.2.6.2";
            File destDir = new File(destDirUrl);
            if (destDir.exists()&&destDir.isDirectory()){
                long fix = System.currentTimeMillis()/ 1000;
                desded.encrypt(srcUrl,
                        destDirUrl+"upgradeMonitor_"+fix+".txt", DESEDE);
            }
        } catch (UnsupportedEncodingException e) {
            System.out.println(e.getMessage());
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}
